# -*- coding: utf-8 -*- 
from google.appengine.api import users
import webapp2
import jinja2
import random
import string
import os
import dal
import hashlib
import time
from google.appengine.api import urlfetch
from CQutils import  EQueueStatus
from google.appengine.api import channel
from django.utils import simplejson

urlfetch.set_default_fetch_deadline(45)

jinja_environment = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))

def get_qr_link(request):
    port = request.environ["SERVER_PORT"]
    proto = request.environ["SERVER_PROTOCOL"].split("/")[0]
    if 'Development' in os.environ['SERVER_SOFTWARE']:
        result = urlfetch.fetch(r'http://curlmyip.com/')
        if result.status_code == 200:
            hostname = result.content
            # hostname = "10.0.0.2"
    else:
        hostname = request.environ["SERVER_NAME"]
    return "http://chart.googleapis.com/chart?chs=200x200&cht=qr&chl=%s://%s:%s/user_page" % (proto, hostname, port)


def generate_random_id():
    return ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(5))


def notify_all(queue_id):
    notify_admin(queue_id)
    notify_users(queue_id)
    
def notify_admin(queue_id):        
    update_dict = {'size': dal.get_queue_size(queue_id)}
    update_dict['users'] = GetQueueUsers.get_users(queue_id)
    update_dict['stats'] = GetQueueStatistics.get_statistics(queue_id)
    update_dict['data'] = GetQueueData.get_queue_data(queue_id)
    channel.send_message(dal.get_admin_queue(queue_id) + queue_id, simplejson.dumps(update_dict))

def notify_users(queue_id):
    users = dal.get_all_users_in_queue(queue_id)
    users.extend([user[0] for user in dal.get_inservice_users(queue_id)])
    for user_id in users:
        update_dict = GetPosInfo.get_pos_info(queue_id, user_id)
        channel.send_message(user_id + queue_id, simplejson.dumps(update_dict))
        

###################### HTML Pages Classes ######################

class MainPage(webapp2.RequestHandler):
    def get(self):
        admin = users.get_current_user()
        logout_url = users.create_logout_url(self.request.uri)
        login_url = users.create_login_url(self.request.uri)

        if admin:
            admin_state = "Yes"
            admin_name = admin.nickname()
        else:
            admin_state = "No"
            admin_name = ''

        template_values = {
            'admin_name': admin_name,
            'login_url': login_url,
            'logout_url': logout_url,
            'admin_state': admin_state,
        }
        template = jinja_environment.get_template('webpages/index3.html')
        self.response.out.write(template.render(template_values))
   

class AdminPage(webapp2.RequestHandler):
    def get(self):
        update_interval = 1000
        admin = users.get_current_user()
        if (admin == None):
            login_url = users.create_login_url(self.request.uri)
            self.redirect(login_url)

        else:  
            admin_name = admin.nickname()
            queues = dal.get_all_queues_from_admin(admin)
            if len(queues) == 0:
                queue_id = "None"
                queue_name = None
                queue_state = None
                queue_op = None
                people_inline = None
                logout_url = users.create_logout_url('/'); 
                current_user = None
                current_phone = None
                statistics = "0 0 0 0"
                queue_type = "0"
            else:
                queue_id = queues[0]
                queue_type = dal.get_queue_type(queue_id)
                queue_name = dal.get_queue_name(queue_id)
                queue_name = queue_name.replace(" ", "-")
                status = dal.get_queue_status(queue_id)
                if status == EQueueStatus.TERMINATED:            
                    queue_state = 'Non-active'
                    queue_op = 'Activate'            
                else:
                    queue_state = 'Active'
                    queue_op = 'Terminate'
                temp = dal.get_queue_statistics(queue_id)
                statistics = str(int(temp[0])) + " " + str(int(temp[1])) + " " + str(int(temp[2])) + " " + str(int(temp[3]))
                people_inline = str(dal.get_queue_size(queue_id))
                logout_url = users.create_logout_url('/');  # need to be changed to appspot.com url
                inservice_users = dal.get_inservice_users(queue_id)
                if len(inservice_users) > 0:
                    current_user = inservice_users[0][0]
                    user_details = dal.get_user_details(current_user)
                    current_user = user_details["name"]
                    current_phone = user_details["phone"]
                    current_user = current_user.replace("-", " ")
                    if current_phone == None:
                        current_phone = ""
                else:
                    (current_user, current_phone) = ("None", " 0 ")
            
            template_values = {
                'admin_name':admin_name,
                'queue_name':queue_name,
                'queue_state':queue_state,
                'queue_op':queue_op,
                'people_inline':people_inline,
                'queue_id':queue_id,
                'logout_url':logout_url,
                'current_user':current_user,
                'current_phone':current_phone,
                'statistics':statistics,
                'update_interval': update_interval,
                'queue_type' : queue_type,
            }

            template = jinja_environment.get_template('webpages/admin_page4.html')
            self.response.out.write(template.render(template_values))


class UserPage(webapp2.RequestHandler): 
    def get(self): 
        queue_type = self.request.get('type')
        queue_id = str(self.request.get("queue_id"))
        queue_name = dal.get_queue_name(queue_id)
        user_id = self.request.cookies.get("CQ_userid")
        if user_id == "":
            user_id = None
        user_name = user_phone = ""
               
        if dal.is_valid_queue(queue_id) == False:
            self.response.out.write("error: queue doesn't exist")
            return

        if user_id is None or dal.is_valid_user(user_id) == False:  # user doesn't exist so redirect it to create user page
            template_values = {
                'queue_id': queue_id,
                'queue_name': queue_name,
                'queue_type': queue_type,
                'user_name': user_name,
                'user_phone': user_phone,
            }
            template = jinja_environment.get_template('webpages/add_user.html')
            self.response.out.write(template.render(template_values))
            return
          
          
        user_pos_id = dal.get_user_pos_in_queue(user_id, queue_id)
        user_in_this_queue = user_pos_id is not None
        user_wainting_anoter_pos = False
        for p in dal.get_user_positions(user_id):
            if p != user_pos_id and dal.get_pos_number(p) >= 0:
                user_wainting_anoter_pos = True
          
        if user_wainting_anoter_pos is True:
            self.response.out.write("you are already waiting in another queue") 
            return
        
        if user_in_this_queue is False:
            dal.join_queue(user_id, queue_id)
            notify_admin(queue_id)
        
        user_details = dal.get_user_details(user_id)
        if user_details is not None:
            user_name = user_details.get("name", "")
            user_phone = user_details.get("phone", "")
                   
        pos_id = dal.get_user_pos_in_queue(user_id, queue_id)
        user_status = dal.get_position_status(pos_id)
    
        update_interval = "5000"
        if (user_status == 0):
            update_interval = "2000"
   
        token = channel.create_channel(user_id + queue_id)
        template_values = {
            'queue_name': queue_name,
            'queue_id': queue_id,
            'user_id': user_id,
            'user_name': user_name,
            'user_phone': user_phone,
            'user_status': user_status,
            'update_interval': update_interval,
            'token' : token
            }
               
        template = jinja_environment.get_template('webpages/user_page.html')
        self.response.out.write(template.render(template_values))
        
        
########## 
class ManualPage(webapp2.RequestHandler):
    def get(self):
        queue_id = self.request.get('queue_id')
        queue_type = self.request.get('type')
        queue_name = dal.get_queue_name(str(queue_id))
        position = -1
        template_values = {
            'qr_url': get_qr_link(self.request),
            'queue_name':queue_name,
            'queue_id':queue_id,
            'position':position,
            'queue_type':queue_type,
            }    
        template = jinja_environment.get_template('webpages/manual_page.html')
        self.response.out.write(template.render(template_values))


########### 
class PrintQr(webapp2.RequestHandler):
    def get(self):
        queue_id = self.request.get('queue_id')     
        queue_type = self.request.get('type')
        queue_name = dal.get_queue_name(str(queue_id))
        template_values = {
            'qr_url':get_qr_link(self.request),
            'queue_id':queue_id,
            'queue_type':queue_type,
            'queue_name':queue_name
            }
        template = jinja_environment.get_template('webpages/print_qr.html')
        self.response.out.write(template.render(template_values))


class HelpPage(webapp2.RequestHandler):
    def get(self):
        admin_name = users.get_current_user()
        if (admin_name):
            login_url = users.create_logout_url(self.request.uri)
            login_text = u"התנתק"
        else:
            login_url = users.create_login_url(self.request.uri)
            login_text = u"התחבר"
            admin_name = u"אינך מחובר"
        template_values = {
        'admin_name':admin_name,
        'login_url':login_url,
        'login_text':login_text
        }
        template = jinja_environment.get_template('webpages/help.html')
        self.response.out.write(template.render(template_values))

class UserPagePreview(webapp2.RequestHandler):
    def get(self):

        template_values = {}  
          
        template = jinja_environment.get_template('webpages/user_page_preview.html')
        self.response.out.write(template.render(template_values))
        

###################### Get Data Classes ######################

########## USER DATA #############    
class GetPosInfo(webapp2.RequestHandler):
    @staticmethod
    def get_pos_info(queue_id, user_id):
        update_dict = {"pos" : GetPosition.get_pos(queue_id, user_id),
                   "est_time" : GetTimeEstimate.get_est_time(queue_id, user_id) }
        return update_dict
    
    def get(self):
        queue_id = self.request.get('queue_id')
        user_id = self.request.get('user_id')
        if user_id is None or user_id == "":
            user_id = self.request.cookies.get("CQ_userid")        
        self.response.out.write(simplejson.dumps(GetPosInfo.get_pos_info(queue_id, user_id)))
            
class GetPosition(webapp2.RequestHandler):
    @staticmethod
    def get_pos(queue_id, user_id, pos_id=None):
        position = -2
        if user_id != "" and  queue_id != "":
            pos_id = dal.get_user_pos_in_queue(user_id, queue_id)
        if pos_id is not None and pos_id != "":
            position = dal.get_pos_number(pos_id)
        return position
    
    def get(self):
        pos_id = self.request.get('pos_id')
        queue_id = self.request.get('queue_id')
        user_id = self.request.get('user_id')
        if user_id is None or user_id == "":
            user_id = self.request.cookies.get("CQ_userid")
        position = GetPosition.get_pos(queue_id, user_id, pos_id)
        self.response.out.write(str(position))
         

class GetTimeEstimate(webapp2.RequestHandler):
    @staticmethod
    def get_est_time(queue_id, user_id):
        queue_stats = dal.get_queue_statistics(queue_id)
        average_time = queue_stats[1]
        user_position = dal.get_pos_number(dal.get_user_pos_in_queue(user_id, queue_id))
        elapsed_time = dal.get_last_service_delta(queue_id)
        estimated_time = (average_time * user_position - elapsed_time) / 60
        if user_position <= 0:
            return -1
        if estimated_time > 0:    
            return int(estimated_time)
        else:
            return 0
        
    def get(self):
        queue_id = self.request.get('queue_id')
        user_id = self.request.get('user_id')
        self.response.out.write(GetTimeEstimate.get_est_time(queue_id, user_id))
                
                
######   ADMIN DATA #########
class GetSize(webapp2.RequestHandler):
    def get(self):
        queue_id = self.request.get('queue_id')
        people_inline = str(dal.get_queue_size(queue_id))
        self.response.out.write(people_inline)


class GetQueues(webapp2.RequestHandler):
    def get(self):
        admin = users.get_current_user()
        queues = dal.get_all_queues_from_admin(admin)
        data = ""
        data_m = ""
        queues_data = []
        for queue_id in queues:
            name = dal.get_queue_name(queue_id)
            queues_data.append({"name" : name, "id" : queue_id})
            # data = data + u'<li><div class="row-fluid nav-tabs"><a class="btn span3" data-toggle="tooltip" title="מחק תור" href="javascript:delete_queue(\'' + str(queue) + '\')"><img src="/img/1378081752_trash.png" width="25" height="25"></img></a><a class="btn span9" style="text-align:right;" onclick="choose_queue(\'' + str(queue) + '\')">' + name + '</a></div></li>'
            # data_m = data_m + u'<li><a style="text-align:right;" href="javascript:choose_queue(\'' + str(queue) + '\');">' + name + '</a></li>'
            
        data = simplejson.dumps(queues_data)
        # self.response.out.write(data + "*****" + data_m)      
        self.response.out.write(data)
        
 
class GetQueueData(webapp2.RequestHandler):
    @staticmethod
    def get_queue_data(queue_id):
        name = dal.get_queue_name(queue_id)
        name = name.replace(" ", "-")
        state = dal.get_queue_status(queue_id)
        status = "Active"
        if state == 1:
            status = "Non-active"
        people_inline = str(dal.get_queue_size(queue_id))
        queue_type = dal.get_queue_type(queue_id)
        inservice_users = dal.get_inservice_users(queue_id)  
        if len(inservice_users) > 0:
            current_user = inservice_users[0][0]
            user_details = dal.get_user_details(current_user)
            current_phone = user_details["phone"]
            if queue_type == 2:
                current_name = current_user
            else: 
                current_name = user_details["name"]
                current_name = current_name.encode('UTF-8')          
        else:
            current_name = "None"
            current_phone = "x"
  
        queue_data = {"size" : people_inline, "status" : status, "name" : name.encode('UTF-8'),
                       " queue_id": queue_id, "curr_name" : current_name,
                       "curr_phone" : current_phone, "type" : queue_type}  
        return queue_data
    
    def get(self):
        queue_id = self.request.get('queue_id')
        queue_data = GetQueueData.get_queue_data(queue_id)
        queue_data["token"] = channel.create_channel(dal.get_admin_queue(queue_id) + queue_id)
        self.response.out.write(simplejson.dumps(queue_data))      
 
 
class GetQueueUsers(webapp2.RequestHandler):
    @staticmethod
    def get_users(queue_id):
        queue_users = dal.get_next_users(queue_id, 10)
        queue_size = dal.get_queue_size(queue_id)
        queue_type = dal.get_queue_type(queue_id)
        pos = 1
        
        identifier = u"שם"
        if queue_type == 2:
            identifier = u"מזהה"
        if queue_type == 1:
            identifier = u"ת.ז"
            
        users_data = []
        for user in queue_users:
            user_details = dal.get_user_details(user)
            user_details["pos"] = pos
            users_data.append(user_details)
            pos = pos + 1
        data = {"size" : queue_size, "id" : identifier, "users" : users_data }
        return data

    def get(self):
        queue_id = self.request.get('queue_id')
        output = GetQueueUsers.get_users(queue_id)
        self.response.out.write(simplejson.dumps(output)) 
        
        
class GetQueueStatistics(webapp2.RequestHandler):
    @staticmethod
    def get_statistics(queue_id):
        temp = dal.get_queue_statistics(queue_id)
        stats = str(int(temp[0])) + " " + str(int(temp[1])) + " " + str(int(temp[2])) + " " + str(int(temp[3]))
        return stats
    
    def get(self):
        queue_id = self.request.get('queue_id')
        stats = GetQueueStatistics.get_statistics(queue_id)
        self.response.out.write(stats)


class QueueOperation(webapp2.RequestHandler):
    def get(self):
        working_queue = self.request.get('queue_id')
        status = dal.get_queue_status(working_queue)
        if (status == 0):
            dal.stop_queue(working_queue)
            self.response.out.write("Non-active")
        else:
            dal.resume_queue(working_queue)
            self.response.out.write("Active")
        # self.redirect('/admin_page')


class GetExtension(webapp2.RequestHandler):
    def get(self):
        queue_id = self.request.get('queue_id')
        user_id = self.request.get('user_id')  
        user_ext = [ext for (u_cqid, ext) in dal.get_inservice_users(queue_id) if u_cqid == user_id]
        extention = -1
        if len(user_ext) > 0:
            extention = user_ext[0]
        self.response.out.write(str(extention))


class GetImage(webapp2.RequestHandler):
    def get(self):
        queue_id = str(self.request.get('queue_id'))
        image = dal.get_queue_image(queue_id)
        if (image):
            self.response.out.write(image)
        else:
            self.redirect("/img/template_background.jpg")


###################### Post Data Classes ######################

class AddQueue(webapp2.RequestHandler):
    def post(self):
        creation_time = str(round(time.time()))
        admin = users.get_current_user()
        admin_id = admin.user_id()
        queue_name = self.request.get('queue_name')
        queue_time = self.request.get('queue_time')
        queue_type = self.request.get('queue_type')
        queue_img = str(self.request.get('queue_img'))
        queue_hash = hashlib.md5(creation_time + admin_id + queue_name.encode("utf-16"))
        queue_id = queue_hash.hexdigest()
        if queue_time is None or queue_time == "":
            queue_time = 0            
        result = dal.create_queue(admin, queue_name, queue_id, int(queue_type), int(queue_time), queue_img,)
        if result is 0:
            time.sleep(3)
            return self.redirect("/admin_page")
        if result is -1:
            template = jinja_environment.get_template('webpages/queue_exist.html')
            self.response.out.write(template.render({'queue_name': queue_name, }))
                
    
class DeleteQueue(webapp2.RequestHandler):
    def get(self):
        queue_id = self.request.get('queue_id') 
        dal.delete_queue(str(queue_id))
        # self.response.out.write(dal.get_queue_name(queue_id) + "- has been deleted!" + str(dal.get_queue_status(queue_id)))    
        self.response.out.write(dal.get_queue_name(queue_id))    
     
     
########## USER OPERATIONS #############
class ManualJoin(webapp2.RequestHandler):
    def get(self):
        queue_id = str(self.request.get('queue_id'))
        user_name = self.request.get('user_name').replace(" ", "-")
        user_phone = self.request.get('user_phone').replace(" ", "").replace("-", "")
        queue_state = str(dal.get_queue_status(queue_id))
        if (user_phone == ""):
            user_phone = "x"    
        if (queue_state == '0'):
            user_details = {"name":user_name, "phone":user_phone}
            user_id = dal.create_user(user_details)
            dal.join_queue(user_id, queue_id)
            self.response.out.write(str(user_id))
        else:
            self.response.out.write("None") 
        notify_admin(queue_id)
     
           
class UserCreate(webapp2.RequestHandler):
    def get(self):        
        queue_id = self.request.get('queue_id')  
        user_name = self.request.get('user_name').replace(" ", "-")
        user_phone = self.request.get('user_phone')
        if (user_phone == ""):
            user_phone = "x"
        user_id = dal.create_user({"name":user_name, "phone":user_phone})       
        self.response.set_cookie("CQ_userid", user_id)  
        self.redirect("/user_page?queue_id=" + queue_id)
       
class UserRejoin(webapp2.RequestHandler):
    def get(self):
        queue_id = self.request.get('queue_id')
        user_id = self.request.cookies.get("CQ_userid")
        dal.join_queue(user_id, queue_id)
        self.redirect("/user_page?queue_id=" + queue_id)
        notify_admin(queue_id)

class DelUser(webapp2.RequestHandler):
    def get(self):
        queue_id = self.request.get('queue_id')
        ext = self.request.get('ext')
        dal.advance_queue(queue_id, ext)
        queue_type = dal.get_queue_type(queue_id)
        inservice_users = dal.get_inservice_users(queue_id)
        if (len(inservice_users) > 0):
            current_user = inservice_users[0][0]
            user_details = dal.get_user_details(current_user)
            current_phone = user_details["phone"]
            if queue_type == 2:
                current_name = current_user
            else: 
                current_name = user_details["name"]
                current_name = current_name.encode('UTF-8')
        else:
            current_name = "None"
            current_phone = "x"
        self.response.out.write(str(dal.get_queue_size(queue_id)) + " " + str(current_name) + " " + current_phone.encode('UTF-8'))
        notify_all(queue_id)

class UserLeave(webapp2.RequestHandler):
    def get(self):
        user_id = self.request.cookies.get("CQ_userid")
        queue_id = self.request.get('queue_id')
        dal.leave_queue(dal.get_user_pos_in_queue(user_id, queue_id))
        self.redirect("/user_page?queue_id=" + queue_id)        
        notify_all(queue_id)


class CallNext(webapp2.RequestHandler):
    def get(self):
        admin = users.get_current_user()
        queues = dal.get_all_queues_from_admin(admin)
        queue_id = queues[0]
        next_user = dal.advance_queue(queue_id)
        self.response.out.write(str(next_user))
    

class SetImage(webapp2.RequestHandler):
    def post(self):
        queue_id = str(self.request.get('queue_id'))
        image = str(self.request.get('imgInp'))
        if (image):
            dal.set_queue_image(queue_id, image)
        return self.redirect("/admin_page")


class DelImage(webapp2.RequestHandler):
    def get(self):
        queue_id = str(self.request.get('queue_id'))
        dal.del_queue_image(queue_id)
  

class PosQueue(webapp2.RedirectHandler):
    def get(self):
        pos_cqid = str(self.request.get('pos_id'))
        self.response.out.write(dal.get_queue_by_position(pos_cqid))
        

###################### Misc Classes ######################

class LogoutCheck(webapp2.RequestHandler):
    def get(self):
        queue_id = str(self.request.get('queue_id'))
        b = (dal.get_queue_size(queue_id) == 0) and (dal.get_queue_status(queue_id) == EQueueStatus.TERMINATED)
        self.response.out.write(b)  


class Test(webapp2.RequestHandler): 
    def get(self):
        queue_id = str(self.request.get('queue_id'))
        if (queue_id):
            queue_image = str(dal.get_queue_image(queue_id))  
            self.response.headers['Content-Type'] = 'image/png'
            self.response.out.write(queue_image) 
        else:
            template = jinja_environment.get_template('webpages/test.html')
            self.response.out.write(template.render())
             
    def post(self):
        image = str(self.request.get('img'))
        queue_id = str(self.request.get('queue_id'))
        dal.set_queue_image(queue_id, image)
        
        self.response.headers['Content-Type'] = 'image/png'
        self.response.out.write(image)
      
 
class ClearDB(webapp2.RequestHandler):  
    def get(self):
        passwd = str(self.request.get('pass'))
        if passwd is None or passwd != "Cl3arE@syQueue":
            return
        
        from google.appengine.ext import db
        from google.appengine.api import memcache
        import models
  
        db.delete(models.DSQueue.all(keys_only=True))
        db.delete(models.DSPosition.all(keys_only=True))
        db.delete(models.DSAdmin.all(keys_only=True))
        db.delete(models.DSUser.all(keys_only=True))
        memcache.Client().flush_all()
        self.response.set_cookie("CQ_userid", None) 
        self.response.out.write("all cleared")


###################### APPLICATION #######################
class GetAllPosition(webapp2.RequestHandler):
    def get(self):
        user_cqid = self.request.get('user_id')
        out = "" 
        if user_cqid != "":
            positions = dal.get_user_positions(user_cqid)
            for pos_id in positions:
                out += pos_id + "\n"
        self.response.out.write(out)

        
###################### Classes Source  ######################

app = webapp2.WSGIApplication([('/test', Test),
                                ('/get_pos_info', GetPosInfo),
                                ('/get_queue_users', GetQueueUsers),
                                ('/get_position', GetPosition),
                                ('/get_time_estimate', GetTimeEstimate),
                                ('/get_size', GetSize),
                                ('/get_image', GetImage),
                                ('/set_image', SetImage),
                                ('/del_image', DelImage),
                                ('/del_user', DelUser),
                                ('/add_queue', AddQueue),
                                ('/user_rejoin', UserRejoin),
                                ('/user_leave', UserLeave),
                                ('/user_page', UserPage),
                                ('/admin_page', AdminPage),
                                ('/print_qr', PrintQr),
                                ('/operate_queue', QueueOperation),
                                ('/call_next', CallNext),
                                ('/logout_check', LogoutCheck),
                                ('/manual_page', ManualPage),
                                ('/manual_join', ManualJoin),
                                ('/auto_join', UserCreate),
                                ('/get_queues', GetQueues),
                                ('/delete_queue', DeleteQueue),
                                ('/get_queue_data', GetQueueData),
                                ('/get_queue_users', GetQueueUsers),
                                ('/get_queue_statistics', GetQueueStatistics),
                                ('/clearDB', ClearDB),
                                ('/get_extension', GetExtension),
                                ('/pos_queue', PosQueue),
                                ('/get_all_positions', GetAllPosition),
                                ('/help', HelpPage),
                                ('/user_page_preview', UserPagePreview),
                                ('/', MainPage)], debug=True)
